package com.atguigu.rabbitmq.topic;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 发送消息，用户下单，快递小哥，把包裹丢到菜鸟驿站
 */
public class Producer {

    public static void main(String[] args) throws Exception {
        // 获取链接工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 设置数据源 主机，端口，用户名，密码，虚拟主机
        connectionFactory.setHost("localhost");
        // 设置端口
        // 15672 : 是后台网站的端口
        // 5672 :  服务器端口
        connectionFactory.setPort(5672);

        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        // 从链接工厂里面获取链接对象
        Connection connection = connectionFactory.newConnection();
        // 通过链接对象，获取频道（信道）
        Channel channel = connection.createChannel();
        // 声明交换机
        // 交换机的作用：接收消息，不会存储消息，还是需要交给队列，需要转发，在转发的过程中需要设置路由规则
//        String exchange, : 表示交换机的名字
//        BuiltinExchangeType type, ： 表示交换机的类型
        // DIRECT("direct"), ： 表示定向发送，精准投放消息
        // FANOUT("fanout"),    表示广播，只要消息发送出去，所有的队列都可以收到消息
        // TOPIC("topic"),  ： 表示模糊匹配 ，在投放消息的时候，可以使用 * 或者 #
//        boolean durable, ： 表示交换机是否需要进行持久化操作
//        boolean autoDelete, ： 表示是否自动删除交换机
//        boolean internal, ：是否内部使用
//        Map<String, Object> arguments　参数
        String exchangeName = "test_topic";
        // 声明交换机
        channel.exchangeDeclare(exchangeName,
                BuiltinExchangeType.TOPIC,
                true, false, false, null);
        // 入门案例不需要交换机，使用系统默认的交换机
        // 省略交换机，直接把消息存到队列，声明一个队列
//        String queue, : 表示队列的名字，名字可以随意取
//        boolean durable, 表示持久化，如果是true，说明服务器如果重启，消息依然存在
//        boolean exclusive, 表示是否独占链接，如果为true，说明客户端会一直占着链接，不会松开
//        boolean autoDelete, 表示如果消息不用了是否会自动删除
//        Map<String, Object> arguments 表示参数
        channel.queueDeclare("test_topic_queue1",
                true,
                false,
                false,
                null);
        channel.queueDeclare("test_topic_queue2",
                true,
                false,
                false,
                null);
        // 需要把交换机里面收到的消息，转发给队列，需要把交换机和队列进行绑定
//        String queue, : 表示，队列名称
        // String exchange, 表示交换机名称
        // String routingKey 队列和交换机进行绑定的时候，设置的路由规则
        channel.queueBind("test_topic_queue1", exchangeName, "#.error");
        channel.queueBind("test_topic_queue1", exchangeName, "order.*");

        channel.queueBind("test_topic_queue2", exchangeName, "*.*");
        // 定义消息
        String message = "订单id=1";
        // 发送消息
//        String exchange, ：接收消息交换机的名称
//        String routingKey, ： 路由规则
//        AMQP.BasicProperties props, ：发送消息的属性
//        byte[] body ：表示消息体
        channel.basicPublish(exchangeName, "info.error", null, message.getBytes("UTF-8"));
        channel.close();
        connection.close();
    }
}
